package net.freebytes.es.common.util;

import com.github.xiaoymin.knife4j.core.util.StrUtil;
import net.freebytes.es.common.repository.PageSortHighLight;
import net.freebytes.es.common.repository.Sort;
import org.elasticsearch.index.query.*;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.search.sort.SortOrder;

import java.util.Collection;
import java.util.HashMap;

/**
 * QueryBuilders的包装类
 *
 * @author 千里明月
 * @date 2021/11/15
 **/
public class QueryBuildersWrapper {


    public static BoolQueryBuilder boolQuery() {
        return new ExBoolQueryBuilders();
    }

    public static <T> WildcardQueryBuilder wildcardQuery(CFunction<T, ?> fn, String value) {
        if (StrUtil.isBlank(value)) {
            return null;
        }
        return QueryBuilders.wildcardQuery(LambdaUtils.getName(fn), value);
    }

    public static <T> TermQueryBuilder termQuery(CFunction<T, ?> fn, Object value) {
        if (value == null) {
            return null;
        }
        if (value instanceof String) {
            if (StrUtil.isBlank((String) value)) {
                return null;
            }
        }
        return new TermQueryBuilder(LambdaUtils.getName(fn), value);
    }


    public static <T> TermsQueryBuilder termsQuery(CFunction<T, ?> fn, Collection<?> values) {
        if(values == null || values.size() <= 0) {
            return null;
        }
        return new TermsQueryBuilder(LambdaUtils.getName(fn), values);
    }

    public static <T> RangeQueryBuilder rangeQuery(CFunction<T, ?> fn, Object start, Object end) {
        if (start == null && end == null) {
            return null;
        }
        if (start instanceof String && end instanceof String) {
            if (StrUtil.isBlank((String) start) && StrUtil.isBlank((String) end)) {
                return null;
            }
        }
        RangeQueryBuilder rangeQueryBuilder = new RangeQueryBuilder(LambdaUtils.getName(fn));
        rangeQueryBuilder.gte(start).lte(end);
        return rangeQueryBuilder;
    }

    public static <T> ExistsQueryBuilder existsQuery(CFunction<T, ?> fn) {
        return new ExistsQueryBuilder(LambdaUtils.getName(fn));
    }

    /**
     * 取模脚本
     * v0 % v1 = v2
     * v0 : 被除数
     * v1 : 除数
     * v2 : 求余的值
     *
     * @author 千里明月
     * @date 2021/11/16
     **/
    public static <T> ScriptQueryBuilder modScript(CFunction<T, ?> fn, Double v1, Integer v2) {
        if (v1 == null || v1 <= 0) {
            return null;
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("v0", LambdaUtils.getName(fn));
        map.put("v1", v1);
        map.put("v2", v2);
        String s = "InternalQlScriptUtils.nullSafeFilter(InternalQlScriptUtils.eq(InternalSqlScriptUtils.mod(InternalQlScriptUtils.docValue(doc,params.v0),params.v1),params.v2))";
        return QueryBuilders.scriptQuery(new Script(ScriptType.INLINE, "painless", s, map));
    }



    /**
     * 简单分页,  默认倒序
     *
     * @param fn 排序字段
     * @author 千里明月
     * @date 2021/11/16
     **/
    public static <T> PageSortHighLight simPage(CFunction<T, ?> fn, Integer pageNo, Integer pageSize) {
        String name = LambdaUtils.getName(fn);
        Sort.Order order = new Sort.Order(SortOrder.DESC, name);
        PageSortHighLight page = new PageSortHighLight(pageNo, pageSize);
        page.setSort(new Sort(order));
        return page;
    }

    /**
     * 简单分页 自定排序
     *
     * @param fn    排序字段
     * @param order 排序
     * @author 千里明月
     * @date 2021/11/16
     **/
    public static <T> PageSortHighLight simPage(CFunction<T, ?> fn, SortOrder order, Integer pageNo, Integer pageSize) {
        String name = LambdaUtils.getName(fn);
        Sort.Order sort = new Sort.Order(order, name);
        PageSortHighLight page = new PageSortHighLight(pageNo, pageSize);
        page.setSort(new Sort(sort));
        return page;
    }

}
